/*
 * Copyright (c) 2007 jNetX.
 * http://www.jnetx.com
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of
 * jNetX. You shall not disclose such Confidential Information and
 * shall use it only in accordance with the terms of the license
 * agreement you entered into with jNetX.
 *
 * $Id$
 */
package com.jnetx.javax.sip.header;

import javax.sip.address.Address;
import javax.sip.header.FromHeader;
import java.text.ParseException;

/**
 * The From header field indicates the logical identity of the initiator
 * of the request, possibly the user's address-of-record. This may be different
 * from the initiator of the dialog.  Requests sent by the callee to the caller
 * use the callee's address in the From header field.
 * <p/>
 * Like the To header field, it contains a URI and optionally a display name,
 * encapsulated in a {@link javax.sip.address.Address}.  It is used by SIP
 * elements to determine which processing rules to apply to a request (for
 * example, automatic call rejection). As such, it is very important that the
 * From URI not contain IP addresses or the FQDN of the host on which the UA is
 * running, since these are not logical names.
 * <p/>
 * The From header field allows for a display name.  A UAC SHOULD use
 * the display name "Anonymous", along with a syntactically correct, but
 * otherwise meaningless URI (like sip:thisis@anonymous.invalid), if the
 * identity of the client is to remain hidden.
 * <p/>
 * Usually, the value that populates the From header field in requests
 * generated by a particular UA is pre-provisioned by the user or by the
 * administrators of the user's local domain.  If a particular UA is used by
 * multiple users, it might have switchable profiles that include a URI
 * corresponding to the identity of the profiled user. Recipients of requests
 * can authenticate the originator of a request in order to ascertain that
 * they are who their From header field claims they are.
 * <p/>
 * Two From header fields are equivalent if their URIs match, and their
 * parameters match. Extension parameters in one header field, not present in
 * the other are ignored for the purposes of comparison. This means that the
 * display name and presence or absence of angle brackets do not affect
 * matching.
 * <ul>
 * <li> The "Tag" parameter - is used in the To and From header fields of SIP
 * messages.  It serves as a general mechanism to identify a dialog, which is
 * the combination of the Call-ID along with two tags, one from each
 * participant in the dialog.  When a User Agent sends a request outside of a dialog,
 * it contains a From tag only, providing "half" of the dialog ID. The dialog
 * is completed from the response(s), each of which contributes the second half
 * in the To header field. When a tag is generated by a User Agent for insertion into
 * a request or response, it MUST be globally unique and cryptographically
 * random with at least 32 bits of randomness. Besides the requirement for
 * global uniqueness, the algorithm for generating a tag is implementation
 * specific.  Tags are helpful in fault tolerant systems, where a dialog is to
 * be recovered on an alternate server after a failure.  A UAS can select the
 * tag in such a way that a backup can recognize a request as part of a dialog
 * on the failed server, and therefore determine that it should attempt to
 * recover the dialog and any other state associated with it.
 * </ul>
 * For Example:<br>
 * <code>From: "Bob" sips:bob@biloxi.com ;tag=a48s<br>
 * From: sip:+12125551212@phone2net.com;tag=887s<br>
 * From: Anonymous sip:c8oqz84zk7z@privacy.org;tag=hyh8</code>
 *
 * @author <a href="mailto:dparhonin@jnetx.ru">Dmitry Parhonin</a>
 * @version $Revision$
 */
public class FromHeaderImpl extends ParametrizedHeaderBase implements FromHeader {
    private Address address;

    private static final FromHeaderParser parser = new FromHeaderParser();

    public FromHeaderImpl() {
        super(FromHeader.NAME);
    }

    FromHeaderImpl(byte[] data, int start, int end) {
        super(FromHeader.NAME, data, start, end);
    }

    public Object clone() {
        final FromHeaderImpl header = new FromHeaderImpl();
        header.cloneBase(this);
        if (parsed) {
            header.cloneParameters(this);
            header.address = this.address;
        }
        return header;
    }

    protected HeaderParser getParser() {
        return parser;
    }

    protected String getValueAsString() {
        return address == null ? "<undefined>" : address.toString();
    }

    /**
     * Sets the tag parameter of the FromHeader. The tag in the From field of a
     * request identifies the peer of the dialog. When a UA sends a request
     * outside of a dialog, it contains a From tag only, providing "half" of
     * the dialog Identifier.
     * <p/>
     * The From Header MUST contain a new "tag" parameter, chosen by the UAC
     * applicaton. Once the initial From "tag" is assigned it should not be
     * manipulated by the application. That is on the client side for outbound
     * requests the application is responsible for Tag assigmennment, after
     * dialog establishment the stack will take care of Tag assignment.
     *
     * @param tag the new tag of the FromHeader
     * @throws java.text.ParseException which signals that an error has been reached
     *                                  unexpectedly while parsing the Tag value.
     */
    public void setTag(String tag) throws ParseException {
        setParameter("tag", tag);
    }

    /**
     * Gets the tag of FromHeader. The Tag parameter identified the Peer of the
     * dialogue and must always be present.
     *
     * @return the tag parameter of the FromHeader.
     */
    public String getTag() {
        return getParameter("tag");
    }

    /**
     * Sets the Address parameter of this Address.
     *
     * @param address the Address object that represents the new
     *                address of this Address.
     */
    public void setAddress(Address address) {
        parse();
        this.address = address;
        invalidateHeaderData();
    }

    /**
     * Gets the address parameter of this Address.
     *
     * @return the Address of this Address
     */
    public Address getAddress() {
        parse();
        return this.address;
    }
}
/*
 * $Log$
 */